/*
		ServEngine framework library
		A library to fast develop JEE online applications
	
		Copyright 2008 José Ignacio de Córdoba Álvaro

		Licensed under the Apache License, Version 2.0 (the "License");
		you may not use this file except in compliance with the License.
		You may obtain a copy of the License at

				http://www.apache.org/licenses/LICENSE-2.0

		Unless required by applicable law or agreed to in writing, software
		distributed under the License is distributed on an "AS IS" BASIS,
		WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
		See the License for the specific language governing permissions and
		limitations under the License.
	
		Jose Ignacio de Cordoba Alvaro
		http://ignacio.decordoba.com
*/

package com.servengine.util;

import com.servengine.struts.ValidatorForm;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;

import java.util.Collection;
import java.util.Comparator;
import java.util.TreeSet;

import org.apache.struts.upload.FormFile;

public class FileManagerActionForm extends ValidatorForm
{
	private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog( FileManagerActionForm.class.getName() );
	private File root,current;
	private long maxfilesize,maxspace;
	private Collection<FileManagerElement> foundfiles;
	private File editfile;
	private FormFile formfile;
	private boolean orderbydate; //FIXME Quizá se necesiten más comparadores.
	private String searchstring;
	private boolean searchfullfilemanager;
	private String filenameargument;
	private String[] removeFiles;
	protected void initFilemanager(String path, boolean create, long maxfilesize, long maxspace)
	{
	  root = new File(path);
	  current=root;
	  if (!root.exists() && create)
	    if (!root.mkdir())
	      log.warn("mkdir could not make dir "+root.getAbsolutePath());
	  if (!root.exists() && create)
	    if (!root.mkdirs())
	      log.warn("mkdirs could not make dir "+root.getAbsolutePath());
	  if (!root.exists())
	      throw new IllegalStateException("Dir doesn't exist: "+path);
		this.maxfilesize=maxfilesize;
		this.maxspace=maxspace;
		log.info("FileManagerClientBean initialized at "+path+"("+(create?"createdir":"")+")"+maxfilesize+"/"+maxspace);
	}
	public TreeSet<FileManagerElement> getList() throws IOException
	{
		TreeSet<FileManagerElement> files = orderbydate==false?new TreeSet<FileManagerElement>():new TreeSet<FileManagerElement>(new OrderByDateComparator(false));
		for(String filename: current.list())
			files.add(new FileManagerElement(current,filename));
		return files;
	}

	public boolean isOrderbydate()
	{
		return orderbydate;
	}

	public void setOrderbydate(boolean value)
	{
		orderbydate=value;
	}

	public void setFoundfiles(Collection<FileManagerElement> foundfiles)
	{
		this.foundfiles = foundfiles;
	}

	public Collection<FileManagerElement> getFoundfiles()
	{
		return foundfiles;
	}
	public String getCurrentAbsolutePath()
	{
		return current.getAbsolutePath();
	}
	public String getCurrentPath()
	{
		return getCurrentAbsolutePath().substring(getRootAbsolutePath().length());
	}
	public String getRootAbsolutePath()
	{
		return root.getAbsolutePath();
	}
	public String[] getCurrentPathArray()
	{
		return getCurrentPath().split(File.separator);
	}
	public String getEditfilename()
	{
		return editfile==null?null:editfile.getName();
	}
	public void setEditfilename(String value)
	{
		if (value.contains(File.separator)) // FIXME pasar esto al validator
			throw new IllegalArgumentException();
		editfile = new File(current,value);
	}
	public File getEditfile()
	{
		return editfile;
	}
	public String getEditfiletext() throws IOException
	{
		StringWriter buffer = new StringWriter();
		BufferedReader reader = new BufferedReader(new FileReader(editfile));
		BufferedWriter writer = new BufferedWriter(buffer);
		String line = null;
		while ((line=reader.readLine())!=null)
		{
			writer.append(line);
			writer.newLine();
		}
		reader.close();
		writer.close();
		return writer.toString();
	}
	public void setEditfiletext(String value) throws IOException
	{
		BufferedWriter writer = new BufferedWriter(new FileWriter(editfile));
		writer.write(value);
		writer.close();
	}
	public boolean isAtrootdir()
	{
		return current.equals(root);
	}
	public long getRootdirlength()
	{
		return dirLength(root);
	}
	private long dirLength(File dir)
	{
				String[] files = dir.list();
		long size = 0;
		if (files!=null)
			for(int n=0; n<files.length; n++)
			{
				File f = new File(dir.getAbsolutePath(),files[n]);
				if (f.isDirectory())
					size+=dirLength(f);
				else
					size+=f.length();
			}
		return size;
	}

	public void setFormfile(FormFile formfile)
	{
		this.formfile = formfile;
	}

	public FormFile getFormfile()
	{
		return formfile;
	}

	public void setSearchstring(String searchstring)
	{
		this.searchstring = searchstring;
	}

	public String getSearchstring()
	{
		return searchstring;
	}

	public void setSearchfullfilemanager(boolean searchfullfilemanager)
	{
		this.searchfullfilemanager = searchfullfilemanager;
	}

	public boolean isSearchfullfilemanager()
	{
		return searchfullfilemanager;
	}

	public File getRoot()
	{
		return root;
	}

	public File getCurrent()
	{
		return current;
	}

	public void setFilenameargument(String newfilename)
	{
	  if (newfilename.contains(File.separator)) // FIXME pasar esto al validator
	    throw new IllegalArgumentException();
		this.filenameargument = newfilename;
	}

	/**
	 *Invoking this method returns filenameargument and resets its value to null.
	 * @return
	 */
	public String getFilenameargument()
	{
		String aux = filenameargument;
		filenameargument=null;
		return aux;
	}

	public void setRemoveFiles(String[] removeFiles)
	{
		this.removeFiles = removeFiles;
	}

	public String[] getRemoveFiles()
	{
		return removeFiles;
	}

	public class OrderByDateComparator implements Comparator
	{
		boolean ascending;
		OrderByDateComparator(boolean ascending)
		{
			this.ascending=ascending;
		}
	
		public int compare(Object file1, Object file2)
		{
		  return ((File)file1).lastModified() > ((File)file2).lastModified() ? (ascending?-1:1):(ascending?1:-1);
		}
	}
	public void setCD(String name)
	{
	  if (name.indexOf("..")>-1)
	  {
	    if (name.equals("..") && current.getParent().indexOf(root.getAbsolutePath())!=-1)
	    {
	      current=new File(current.getParent());
				return;
	    }
	  } else
	  {
	    File temp = new File(getCurrentAbsolutePath()+"/"+name);
	    if(temp.isDirectory())
	    {
	      current = temp;
	      return;
	    }
	  }
	  throw new IllegalArgumentException("No such directory "+name+" accesible from current path");
	}
	public void setToroot(boolean value)
	{
		if (value)
			current = root;
	}
}
